package inabit.base;

import inabit.data.Variable;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**This class manages the variables using during the inference process
 * @author Rafael Rocha*/
public class WorkingMemory {
	private Map<String, Variable> variableMap;
	
	public WorkingMemory() {
		variableMap = new HashMap<String, Variable>();
	}
	
	public void addVariable(Variable var) {
		variableMap.put(var.getID(), var);
	}
	public void removeVariable(String id) {
		variableMap.remove(id);
	}
	public Variable getVariable(String id) {
		return variableMap.get(id);
	}
	public Collection<Variable> getVariables() {
		return variableMap.values();
	}
	public boolean hasVariable(String id) {
		return variableMap.containsKey(id);
	}
	/**Returns the value attached to variable specified by the current id
	 * it will throw a NullPointerException if the variable wasn't found at
	 * the working memory, returns null if the variable has no value associated.*/
	public String getVariableValue(String id) {
		return variableMap.get(id).getValue();
	}
	
	/**Set the value of the specified variable. It can throw a NullPointerException if
	 * the variable wasn't found at working memory or a different Exception if the
	 * value isn't acceptable to the variable*/
	public void setVariableValue(String id, String value) {
		variableMap.get(id).setValue(value);
	}
	
	/**Saves the values of the current variables, so that if the state is restored the values
	 * will not be lost*/
	public void saveState() {
		for(Variable var : variableMap.values()) {
			var.save();
		}
	}
	/**Restores the working memory to the last saved state, if the state wasn't saved the values
	 * of all variables are set to null.*/
	public void restoreState() {
		for(Variable var : variableMap.values()){
			var.restore();
		}
	}
	
	public void addVariables(Collection<Variable> variables) {
		for(Variable var : variables) {
			addVariable(var);
		}
	}

	public void removeAll(Collection<Variable> variables) {
		List<String> deletedVars = new ArrayList<String>();
		for(Variable var : variables) {
			deletedVars.add(var.getID());
		}
		for(String id : deletedVars){
			removeVariable(id);
		}
	}
	
}
